package org.roger.sort;

import java.io.IOException;

import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.SortedDocValues;
import org.apache.lucene.search.FieldComparator;
import org.apache.lucene.search.FieldComparatorSource;
import org.apache.lucene.search.LeafFieldComparator;
import org.apache.lucene.search.Scorer;
import org.roger.util.DistanceUtil;

/**
 * 自定义距离排序（文档当前的点到（x,y）的距离）
 * @param x 横坐标
 * @param y 纵坐标
 * @author luoweiyi
 */
public class DistanceComparatorSource extends FieldComparatorSource{
	
	private int x;
	private int y;
	
	public DistanceComparatorSource(int x,int y){
		this.x = x;
		this.y = y;
	}

	@Override
	public FieldComparator<?> newComparator(String fieldname, int numHits,
			int sortPos, boolean reversed) throws IOException {
		return new DistanceScoreDocLookupComparator(fieldname,numHits);
	}
	
	private class DistanceScoreDocLookupComparator extends FieldComparator<Double> implements LeafFieldComparator {

		private int[] xDoc, yDoc;
		
		private double[] values;
		
		private Double bottom;//评分结果最低
		private Double topValue;
		SortedDocValues termsIndex;
		
		String fieldName;
		
		public DistanceScoreDocLookupComparator(String fieldName,int numHits){
			values = new double[numHits];
			this.fieldName = fieldName;
		}
		
		@Override
		public int compare(int slot1, int slot2) {
			if(values[slot1] > values[slot2])return 1;
			if(values[slot1] < values[slot2])return -1;
			return 0;
		}		
		public void setBottom(int slot) {
			bottom = values[slot];
		}

		public int compareBottom(int doc) throws IOException {
			double dis = DistanceUtil.getDistance(xDoc[doc]-x, yDoc[doc]-y);
			if(bottom > dis) return 1;
			if(bottom < dis) return -1;
			return 0;
		}


		public void copy(int slot, int doc) throws IOException {
			//得到文档到点（x,y）的实际距离
			values[slot] = DistanceUtil.getDistance(xDoc[doc]-x, yDoc[doc]-y);
		}

		@Override
		public Double value(int slot) {
			return new Double(values[slot]);
		}

		@Override
		public LeafFieldComparator getLeafComparator(LeafReaderContext context) throws IOException {
			termsIndex = DocValues.getSorted(context.reader(), fieldName);
			return this;
		}

		@Override
		public void setTopValue(Double arg0) {
			topValue = arg0;
		}

		@Override
		public int compareTop(int doc) throws IOException {
			int ord = termsIndex.getOrd(doc);
			return ord > 0 ? -1 : 1;
		}

		@Override
		public void setScorer(Scorer scorer) {
		}
	}
}
